<script>
	import G6 from '@antv/g6';
	import { onMount } from 'svelte';

	const Util = G6.Util;
	const data = {
		nodes: [
			{
				id: 'node1',
				x: 100,
				y: 100,
				type: 'circle-animate',
				size: 20,
				label: 'Scale Animation',
				labelCfg: {
					position: 'top'
				}
			},
			{
				id: 'node2',
				x: 300,
				y: 200,
				type: 'background-animate',
				color: '#40a9ff',
				size: 20,
				label: 'Background Animation',
				labelCfg: {
					position: 'left',
					offset: 10
				}
			},
			{
				id: 'node3',
				x: 400,
				y: 100,
				size: [40, 40],
				type: 'inner-animate',
				img: '',
				label: 'Image Rotate',
				labelCfg: {
					position: 'right'
				}
			},
			{
				id: 'node4',
				x: 300,
				y: 300,
				type: 'rect',
				label: 'No Animation',
				labelCfg: {
					position: 'bottom'
				}
			}
		],
		edges: [
			{
				source: 'node1',
				target: 'node2'
			},
			{
				source: 'node3',
				target: 'node2'
			},
			{
				source: 'node2',
				target: 'node4'
			}
		]
	};
	// Scale Animation
	G6.registerNode(
		'circle-animate',
		{
			afterDraw(cfg, group) {
				const shape = group.get('children')[0];
				shape.animate(
					(ratio) => {
						const diff = ratio <= 0.5 ? ratio * 10 : (1 - ratio) * 10;
						return {
							r: cfg.size / 2 + diff
						};
					},
					{
						repeat: true,
						duration: 3000,
						easing: 'easeCubic'
					}
				);
			}
		},
		'circle'
	);

	// Background Animation
	G6.registerNode(
		'background-animate',
		{
			afterDraw(cfg, group) {
				const r = cfg.size / 2;
				const back1 = group.addShape('circle', {
					zIndex: -3,
					attrs: {
						x: 0,
						y: 0,
						r,
						fill: cfg.color,
						opacity: 0.6
					},
					name: 'back1-shape'
				});
				const back2 = group.addShape('circle', {
					zIndex: -2,
					attrs: {
						x: 0,
						y: 0,
						r,
						fill: cfg.color,
						opacity: 0.6
					},
					name: 'back2-shape'
				});
				const back3 = group.addShape('circle', {
					zIndex: -1,
					attrs: {
						x: 0,
						y: 0,
						r,
						fill: cfg.color,
						opacity: 0.6
					},
					name: 'back3-shape'
				});
				group.sort(); // Sort according to the zIndex
				back1.animate(
					{
						// Magnifying and disappearing
						r: r + 10,
						opacity: 0.1
					},
					{
						duration: 3000,
						easing: 'easeCubic',
						delay: 0,
						repeat: true // repeat
					}
				); // no delay
				back2.animate(
					{
						// Magnifying and disappearing
						r: r + 10,
						opacity: 0.1
					},
					{
						duration: 3000,
						easing: 'easeCubic',
						delay: 1000,
						repeat: true // repeat
					}
				); // 1s delay
				back3.animate(
					{
						// Magnifying and disappearing
						r: r + 10,
						opacity: 0.1
					},
					{
						duration: 3000,
						easing: 'easeCubic',
						delay: 2000,
						repeat: true // repeat
					}
				); // 3s delay
			}
		},
		'circle'
	);

	// Image animation
	G6.registerNode(
		'inner-animate',
		{
			afterDraw(cfg, group) {
				const size = cfg.size;
				const width = size[0] - 12;
				const height = size[1] - 12;
				const image = group.addShape('image', {
					attrs: {
						x: -width / 2,
						y: -height / 2,
						width,
						height,
						img: cfg.img
					},
					name: 'image-shape'
				});
				image.animate(
					(ratio) => {
						const toMatrix = Util.transform(
							[1, 0, 0, 0, 1, 0, 0, 0, 1],
							[['r', ratio * Math.PI * 2]]
						);
						return {
							matrix: toMatrix
						};
					},
					{
						repeat: true,
						duration: 3000,
						easing: 'easeCubic'
					}
				);
			}
		},
		'rect'
	);
	onMount(() => {
		const graph = new G6.Graph({
			container: 'demo', // 指定挂载容器
			width: 1000,
			height: 600,
			defaultNode: {
				// ... 其他属性
				label: 'node-label',
				labelCfg: {
					position: 'bottom',
					offset: 10,
					style: {
						fill: '#f40'
					}
				},

				style: {
					fill: '#f40',
					stroke: 'green'
				}
			},
			defaultEdge: {
				style: {
					lineWidth: 1,
					stroke: '#b5b5b5'
				}
			}
		});
		graph.data(data);
		graph.render();

		if (typeof window !== 'undefined')
			window.onresize = () => {
				if (!graph || graph.get('destroyed')) return;
				if (!container || !container.scrollWidth || !container.scrollHeight) return;
				graph.changeSize(container.scrollWidth, container.scrollHeight);
			};
	});
</script>

<div id="demo" />
